/*
 * MainForm.java
 *
 * Created on 26/02/2011, 18:52:45
 *
 * Este formulario trabajará con los parser SAX y DOM para mostrar su funcionalidad
 */

package xmljparser;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.JFileChooser;
import java.io.File;
import javax.swing.filechooser.FileFilter;
import xml.parserDOM.Arbol;
import xml.parserSAX.SAXException;
import xml.parserSAX.SAXHandler;
import xml.parserSAX.SAXParser;
import Clases.Atributo;
import xml.parserDOM.DOMParser;
import xml.parserDOM.Nodo;
import Clases.Tag;
import javax.swing.JOptionPane;
import xml.io.xmlReader;
import xml.parserDTD.GenerarDOMDTD;
/**
 *
 * @author Lucas & Diego
 */
public class MainForm extends javax.swing.JFrame
{
    private DefaultMutableTreeNode root;
    private DefaultTreeModel mdl;

    /** Creates new form MainForm */
    public MainForm()
    {
        initComponents();
        inicializarFormulario();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jToolBar1 = new javax.swing.JToolBar();
        btnAbrir = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        btnParserSax = new javax.swing.JToggleButton();
        btnParserDom = new javax.swing.JToggleButton();
        jcbIgnorarEB = new javax.swing.JCheckBox();
        jSeparator2 = new javax.swing.JToolBar.Separator();
        btnSalir = new javax.swing.JButton();
        pnlStatus = new javax.swing.JPanel();
        lblPath = new javax.swing.JLabel();
        lblStatus = new javax.swing.JLabel();
        jSplitPane1 = new javax.swing.JSplitPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        jtxMemo = new javax.swing.JTextArea();
        jScrollPane2 = new javax.swing.JScrollPane();
        jtvArbol = new javax.swing.JTree();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jToolBar1.setRollover(true);

        btnAbrir.setText("Abrir");
        btnAbrir.setFocusable(false);
        btnAbrir.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnAbrir.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnAbrir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAbrirActionPerformed(evt);
            }
        });
        jToolBar1.add(btnAbrir);
        jToolBar1.add(jSeparator1);

        btnParserSax.setSelected(true);
        btnParserSax.setText("SAX");
        btnParserSax.setFocusable(false);
        btnParserSax.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnParserSax.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnParserSax.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnParserSaxActionPerformed(evt);
            }
        });
        jToolBar1.add(btnParserSax);

        btnParserDom.setText("DOM");
        btnParserDom.setFocusable(false);
        btnParserDom.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnParserDom.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnParserDom.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnParserDomActionPerformed(evt);
            }
        });
        jToolBar1.add(btnParserDom);

        jcbIgnorarEB.setText("ignorar espacios en blanco");
        jcbIgnorarEB.setFocusable(false);
        jcbIgnorarEB.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        jcbIgnorarEB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar1.add(jcbIgnorarEB);

        jSeparator2.setPreferredSize(new java.awt.Dimension(60, 0));
        jToolBar1.add(jSeparator2);

        btnSalir.setText("Salir");
        btnSalir.setFocusable(false);
        btnSalir.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnSalir.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnSalir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSalirActionPerformed(evt);
            }
        });
        jToolBar1.add(btnSalir);

        getContentPane().add(jToolBar1, java.awt.BorderLayout.PAGE_START);

        pnlStatus.setPreferredSize(new java.awt.Dimension(537, 35));

        lblPath.setText("jLabel1");

        lblStatus.setText("jLabel2");

        javax.swing.GroupLayout pnlStatusLayout = new javax.swing.GroupLayout(pnlStatus);
        pnlStatus.setLayout(pnlStatusLayout);
        pnlStatusLayout.setHorizontalGroup(
            pnlStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlStatusLayout.createSequentialGroup()
                .addGroup(pnlStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(lblStatus)
                    .addComponent(lblPath))
                .addContainerGap(685, Short.MAX_VALUE))
        );
        pnlStatusLayout.setVerticalGroup(
            pnlStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlStatusLayout.createSequentialGroup()
                .addComponent(lblStatus)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lblPath)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        getContentPane().add(pnlStatus, java.awt.BorderLayout.PAGE_END);

        jSplitPane1.setDividerLocation(300);

        jtxMemo.setColumns(20);
        jtxMemo.setRows(5);
        jScrollPane1.setViewportView(jtxMemo);

        jSplitPane1.setLeftComponent(jScrollPane1);

        jtvArbol.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        jScrollPane2.setViewportView(jtvArbol);

        jSplitPane1.setRightComponent(jScrollPane2);

        getContentPane().add(jSplitPane1, java.awt.BorderLayout.CENTER);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnParserSaxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnParserSaxActionPerformed
        btnParserDom.setSelected(!btnParserSax.isSelected());
    }//GEN-LAST:event_btnParserSaxActionPerformed

    private void btnParserDomActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnParserDomActionPerformed
        btnParserSax.setSelected(!btnParserDom.isSelected());
    }//GEN-LAST:event_btnParserDomActionPerformed

    private void btnAbrirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAbrirActionPerformed
        //path del archivo a parsear
        lblPath.setText(null);
        //Limpiamos los resultados anteriores, si los hay
        mdl = new DefaultTreeModel(null);
        jtvArbol.setModel(mdl);
        jtxMemo.setText("");
        JFileChooser jfc = new JFileChooser();
        jfc.setMultiSelectionEnabled(false);
        jfc.setFileFilter(new MyFileFilter());

        if (jfc.showOpenDialog(getRootPane()) == JFileChooser.APPROVE_OPTION)
        {
            //una vez seleccionado el archivo muestro el path en la aplicacion
            lblPath.setText(jfc.getSelectedFile().getAbsolutePath());
            
            //si va a utilizar solo el parser SAX creo una instancia del handler
            if (btnParserSax.isSelected())
            {
                try
                {
                    //el constructor del parser recibe el path del archivo
                    //y una instancia de un sax handler
                    jtxMemo.setText(null);
                    SAXParser p = new SAXParser(lblPath.getText(), new MySAXHandler(), jcbIgnorarEB.isSelected());
                    p.parsing();
                }
                catch (FileNotFoundException ex)
                {
                    JOptionPane.showMessageDialog(this, ex.getMessage());
                }
                catch (IOException ex)
                {
                    JOptionPane.showMessageDialog(this, ex.getMessage());
                }
                catch (SAXException ex)
                {
                    JOptionPane.showMessageDialog(this, ex.getMessage());
                }
            }
            else if (btnParserDom.isSelected())
            {
                //pasamos el path del archivo asi se crea el Arbol Dom
                //y lo mostramos en el tree
                try {
                    Arbol arb = new DOMParser(lblPath.getText(), new MySAXHandler()).tree;
                    if (arb.getDocInfo() != null){
                    //String sDTD = jfc.getSelectedFile().getAbsolutePath().replace(".xml", ".dtd");
                    File fDTD = new File(arb.getDocInfo());
                    if (fDTD.exists()){
                        String[] dtd = xmlReader.read(fDTD);
                        GenerarDOMDTD.generarDTD(dtd, arb);
                    }}
                    addArbol(arb);
                } catch (SAXException ex) {
                    JOptionPane.showMessageDialog(this, ex.getMessage());
                } catch (IOException ex) {
                    JOptionPane.showMessageDialog(this, ex.getMessage());
                }
            }
        }
    }//GEN-LAST:event_btnAbrirActionPerformed

    private void btnSalirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSalirActionPerformed
        System.exit(0);
    }//GEN-LAST:event_btnSalirActionPerformed

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new MainForm().setVisible(true);
            }
        });
    }


    // <editor-fold defaultstate="collapsed" desc="Nuestro Código">
    /**
     * Clase para seleccionar archivos xml solamente
     */
    class MyFileFilter extends FileFilter
    {
        @Override
        public boolean accept(File f)
        {
            return (f.isDirectory()) | (f.getName().toLowerCase().endsWith(".xml"));
        }

        @Override
        public String getDescription()
        {
            return "Archivos XML (*.xml)";
        }
    }

    class MySAXHandler extends SAXHandler
    {

        @Override
        public void startDocument(String nombre){
            jtxMemo.append("Comienzo del procesamiento del documento..."+nombre+"\n");
            //throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public void startElement(String qName, Atributo attributes) {
            jtxMemo.append("Comienza elemento: " + qName + "\n");
            //throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public void characters(String characters) {
            jtxMemo.append("[ " +characters + " ]\n");
        }

        @Override
        public void endElement(String uri, String localName, String qName) {
            jtxMemo.append("Finaliza Elemento: " + qName + "\n");
            //throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public void endDocument() {
            jtxMemo.append("Fin del procesamiento del documento.\n");
            //throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public void processCommand(String command) {
            jtxMemo.append("Procesando instruccion: [" + command + "]\n");
//            throw new UnsupportedOperationException("Not supported yet.");
        }
        
    }


    private void addArbol(Arbol t){
        if ((t != null) && (t.getRootElement() != null)) {
            Nodo<Tag> re = t.getRootElement();
            String dat;
            if (re.getNumberOfChildren() == 0) {
                dat = re.getDato();
            } else {
                dat = re.getTag().getQname();
            }
            DefaultMutableTreeNode rt = new DefaultMutableTreeNode(dat);

            mdl.setRoot(rt);
            for (Nodo<Tag> h : re.getChildren()) {
                if (h.getNumberOfChildren() == 0) {
                    dat = h.getDato();
                } else {
                    dat = h.getTag().getQname();
                }
                DefaultMutableTreeNode ct = new DefaultMutableTreeNode(dat);
                rt.add(ct);
                addNodoHijo(h, ct);
            }
            if (re.getNumberOfChildren() > 0){
                jtvArbol.expandRow(0);
            }
        }
    }
    
    private void addNodoHijo(Nodo<Tag> n, DefaultMutableTreeNode nene){
        if (n.getNumberOfChildren() > 0) {
            for (Nodo<Tag> h : n.getChildren()) {
                String dat;
                if (h.getNumberOfChildren() == 0) {
                    dat = h.getDato();
                } else {
                    dat = h.getTag().getQname();
                }
                DefaultMutableTreeNode ct = new DefaultMutableTreeNode(dat);
                nene.add(ct);
                addNodoHijo(h, ct);
            }
        }
    }

    /*
     * Setea algunas inicializaciones
     */
    private void inicializarFormulario()
    {
        lblStatus.setText(null);
        lblPath.setText(null);

        mdl = new DefaultTreeModel(null);
        jtvArbol.setModel(mdl);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Componentes del formulario">

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAbrir;
    private javax.swing.JToggleButton btnParserDom;
    private javax.swing.JToggleButton btnParserSax;
    private javax.swing.JButton btnSalir;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JToolBar.Separator jSeparator2;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JCheckBox jcbIgnorarEB;
    private javax.swing.JTree jtvArbol;
    private javax.swing.JTextArea jtxMemo;
    private javax.swing.JLabel lblPath;
    private javax.swing.JLabel lblStatus;
    private javax.swing.JPanel pnlStatus;
    // End of variables declaration//GEN-END:variables

    // </editor-fold>    
}
